package com.catchman.demo.service;

import com.catchman.demo.domain.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author catchman
 */
@Transactional(rollbackFor = Exception.class)
public interface UserRepository extends JpaRepository<User,Long> {
    /******************************create***************************************/
    @Override
    User save(User user);
    /******************************read***************************************/
    /**
     * Using sort
     * @param firstName
     * @param sort
     * @return
     */
    @Query("select u from User u where u.firstName like ?1%")
    List<User> findByAndSort(String firstName, Sort sort);
    /**
     * Query creation
     * this translates into the following query:
     * select u from User u where u.idCard = ?1
     */
//    User findByFirstName(String firstName);

    /**
     * Declare native count queries for pagination at the query method by using @Query
     * @param pageable
     * @return
     */
    @Query(value = "SELECT * FROM USER",
            countQuery = "SELECT count(*) FROM USER",
            nativeQuery = true)
    Page<User> findALLWithPageable(Pageable pageable);

    /**
     * Using Named Parameters
     * @param firstName
     * @param id
     * @return
     */
    @Query("select u from User u where u.firstName = :firstName or u.id = :id")
    List<User> findByFirstNameOrLastName(@Param("firstName") String firstName,
                                         @Param("id") String id);

    /**
     * findByFirstName
     * @param firstName
     * @return
     */
    List<User> findByFirstName(@Param("firstName") String firstName);

    /**
     * find all usersupdateUser
     * @param sort
     * @return
     */
    @Override
    List<User> findAll(Sort sort);
    /****************************update*****************************************/
    /**
     * update a usr by Modifying Queries
     * @param firstName
     * @param id
     * @return
     */
    @Modifying
    @Query("update User u set u.firstName = ?1 where u.id = ?2")
    int updateUser(String firstName, Long id);
    /****************************delete*****************************************/
    /**
     * delete a user by idCard
     * @param id
     */
    void deleteById(long id);

    /**
     * Using a derived delete query
     * @param id
     */
    @Modifying
    @Query("delete from User u where u.id = ?1")
    void deleteById2(long id);

    /**
     * delete a user by id
     * @param id
     */
    @Override
    @Modifying
    @Query(value = "delete from User where USE_ID = ?1", nativeQuery = true)
    void deleteById(Long id);
}
